package com.aw.baselib.util

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Environment
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
import androidx.core.os.EnvironmentCompat
import com.aw.baselib.base.AwBaseApplication
import com.aw.baselib.util.AwDataUtil.isEmpty
import java.io.BufferedReader
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.FileWriter
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.io.Serializable
import java.math.BigDecimal
import java.net.HttpURLConnection
import java.net.URL
import java.text.DecimalFormat
import java.util.Locale
import java.util.Properties

/**
 * 文件工具类
 *
 * @author joey.huang
 */
object AwFileUtil {
    private const val TAG = "FileUtil"
    const val SIZETYPE_B = 1 // 获取文件大小单位为B的double值
    const val SIZETYPE_KB = 2 // 获取文件大小单位为KB的double值
    const val SIZETYPE_MB = 3 // 获取文件大小单位为MB的double值
    const val SIZETYPE_GB = 4 // 获取文件大小单位为GB的double值
    fun testAddress(mContext: Context) {
        // 获取缓存目录 程序卸载后自动删除
        AwLog.d(
            TAG, """
     获取缓存目录路径, 程序卸载后自动删除
     getExternalCacheDir: ${mContext.externalCacheDir}
     """.trimIndent()
        )
        // 应用在外部存储上的目录的file文件夹
        AwLog.d(
            TAG, """
     应用在外部存储上的目录的file文件夹路径
     getExternalFilesDir: ${mContext.getExternalFilesDir("")}
     """.trimIndent()
        )
        // 相机拍摄的图片和视频保存的位置
        AwLog.d(
            TAG, """
     相机拍摄的图片和视频保存路径
     getExternalFilesDir<Environment.DIRECTORY_DCIM>: ${mContext.getExternalFilesDir(Environment.DIRECTORY_DCIM)}
     """.trimIndent()
        )
        // 警报的铃声
        AwLog.d(
            TAG, """
     警报的铃声保存路径
     getExternalFilesDir<Environment.DIRECTORY_ALARMS>: ${mContext.getExternalFilesDir(Environment.DIRECTORY_ALARMS)}
     """.trimIndent()
        )
        // 下载文件保存的位置
        AwLog.d(
            TAG, """
     下载文件保存路径
     getExternalFilesDir<Environment.DIRECTORY_DOWNLOADS>: ${
                mContext.getExternalFilesDir(
                    Environment.DIRECTORY_DOWNLOADS
                )
            }
     """.trimIndent()
        )
        // 电影保存的位置
        AwLog.d(
            TAG, """
     电影保存路径
     getExternalFilesDir<Environment.DIRECTORY_MOVIES>: ${mContext.getExternalFilesDir(Environment.DIRECTORY_MOVIES)}
     """.trimIndent()
        )
        // 音乐保存的位置
        AwLog.d(
            TAG, """
     音乐保存路径
     getExternalFilesDir<Environment.DIRECTORY_MUSIC>: ${mContext.getExternalFilesDir(Environment.DIRECTORY_MUSIC)}
     """.trimIndent()
        )
        // 通知音保存的位置
        AwLog.d(
            TAG, """
     通知音保存路径
     getExternalFilesDir<Environment.DIRECTORY_NOTIFICATIONS>: ${
                mContext.getExternalFilesDir(
                    Environment.DIRECTORY_NOTIFICATIONS
                )
            }
     """.trimIndent()
        )
        // 下载的图片保存的位置
        AwLog.d(
            TAG, """
     下载图片保存路径
     getExternalFilesDir<Environment.DIRECTORY_PICTURES>: ${mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES)}
     """.trimIndent()
        )
        // 用于保存(博客)的音频文件
        AwLog.d(
            TAG, """
     博客等音频保存路径
     getExternalFilesDir<Environment.DIRECTORY_PODCASTS>: ${mContext.getExternalFilesDir(Environment.DIRECTORY_PODCASTS)}
     """.trimIndent()
        )
        // 保存铃声的位置
        AwLog.d(
            TAG, """
     铃声保存路径
     getExternalFilesDir<Environment.DIRECTORY_RINGTONES>: ${
                mContext.getExternalFilesDir(
                    Environment.DIRECTORY_RINGTONES
                )
            }
     """.trimIndent()
        )
        // 获取 Android 数据目录
        AwLog.d(
            TAG, """
     Android 数据目录路径
     getDataDirectory: ${Environment.getDataDirectory()}
     """.trimIndent()
        )
        // 获取 Android 下载/缓存内容目录
        AwLog.d(
            TAG, """
     Android 下载/缓存内容目录路径
     getDownloadCacheDirectory: ${Environment.getDownloadCacheDirectory()}
     """.trimIndent()
        )
        // sdcard路径 常用
        AwLog.d(
            TAG, """
     SD卡常用路径
     getExternalStorageDirectory: ${Environment.getExternalStorageDirectory()}
     """.trimIndent()
        )
        // 同 this.getExternalFilesDir(...)
        AwLog.d(
            TAG, """
     应用在外部存储上的目录的file文件夹路径<可直接创建>
     getExternalStoragePublicDirectory: ${Environment.getExternalStoragePublicDirectory("")}
     """.trimIndent()
        )
        //agentWeb默认缓存地址测试
        AwLog.d(TAG, "agentWeb getCachePath: " + getCachePath(mContext))
        //agentWeb默认缓存地址测试
        AwLog.d(TAG, "agentWeb getExternalCachePath: " + getExternalCachePath(mContext))
        //data/data
        AwLog.d(TAG, "getDir app_webview: " + mContext.getDir("webview", Context.MODE_PRIVATE))
        AwLog.d(TAG, "getDir app_textures: " + mContext.getDir("textures", Context.MODE_PRIVATE))
        AwLog.d(TAG, "getDir databases: " + mContext.getDir("database", Context.MODE_PRIVATE))
    }

    const val FILE_CACHE_PATH = "agentweb-cache"
    val AGENTWEB_CACHE_PATCH = File.separator + "agentweb-cache"
    var AGENTWEB_FILE_PATH: String? = null
    fun getAgentWebFilePath(context: Context): String? {
        if (!TextUtils.isEmpty(AGENTWEB_FILE_PATH)) {
            return AGENTWEB_FILE_PATH
        }
        val dir = getDiskExternalCacheDir(context)
        val mFile = File(dir, FILE_CACHE_PATH)
        try {
            if (!mFile.exists()) {
                mFile.mkdirs()
            }
        } catch (throwable: Throwable) {
            AwLog.d(TAG, "create dir exception")
        }
        AwLog.d(TAG, "path:" + mFile.absolutePath + "  path:" + mFile.path)
        return mFile.absolutePath.also { AGENTWEB_FILE_PATH = it }
    }

    fun getDiskExternalCacheDir(context: Context): String? {
        val mFile = context.externalCacheDir
        return if (Environment.MEDIA_MOUNTED == EnvironmentCompat.getStorageState(
                mFile!!
            )
        ) {
            mFile.absolutePath
        } else null
    }

    /**
     * @param context
     * @return WebView 的缓存路径
     */
    fun getCachePath(context: Context): String {
        return context.cacheDir.absolutePath + AGENTWEB_CACHE_PATCH
    }

    /**
     * @param context
     * @return AgentWeb 缓存路径
     */
    fun getExternalCachePath(context: Context): String? {
        return getAgentWebFilePath(context)
    }

    fun writeFile(context: Context, fileName: String, content: String?): String {
        val filePath = context.getExternalFilesDir("")!!.absolutePath + "/" + fileName
        var writer: FileWriter? = null
        try {
            val f = File(filePath)
            if (f.exists()) {
                f.delete()
            }
            f.createNewFile()
            writer = FileWriter(f, true)
            writer.write(content)
            writer.flush()
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            try {
                writer!!.close()
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
        return filePath
    }

    /**
     * 读取指定文件
     *
     * @param filePath
     * @return
     */
    fun loadFromSDFile(filePath: String?): String? {
        if (isEmpty(filePath)) return ""
        var result: String? = null
        try {
            val f = File(filePath)
            val length = f.length().toInt()
            val buff = ByteArray(length)
            val fin = FileInputStream(f)
            fin.read(buff)
            fin.close()
            result = String(buff, Charsets.UTF_8)
        } catch (e: Exception) {
            e.printStackTrace()
            Toast.makeText(AwBaseApplication.instance, "没有找到指定文件", Toast.LENGTH_SHORT)
                .show()
        }
        return result
    }

    fun readFileOnLine(filePath: String?): String {
        if (isEmpty(filePath)) return ""
        try {
            val f = File(filePath)
            //            FileInputStream fis = new FileInputStream(f, "UTF-8");
//            StringBuffer sb = new StringBuffer();
//            DataInputStream dataIO = new DataInputStream(fis);
//            String strLine = "";
//            while ((strLine = dataIO.readLine()) != null) {
//				if(!strLine.contains("{")) {
//					sb.append(strLine).append("\n");
//				} else {
//					sb.append("");
//				}
//            }
//            dataIO.close();
//            fis.close();
//            return sb.toString();
            val sb = StringBuffer()
            val inputStream: InputStream = FileInputStream(f)
            val inputStreamReader = InputStreamReader(inputStream, "UTF-8")
            val bufferedReader = BufferedReader(inputStreamReader)
            var line: String
            while (bufferedReader.readLine().also { line = it } != null) {
                if (!line.contains("{")) {
                    sb.append(line).append("\n")
                } else {
                    sb.append("")
                }
            }
            bufferedReader.close()
            return sb.toString()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return ""
    }

    /**
     * 复制文件
     *
     * @param srcFile
     * @param destFile
     * @return
     * @throws IOException
     */
    @Throws(IOException::class)
    fun copyFileTo(srcFile: File, destFile: File): Boolean {
        if (srcFile.isDirectory || destFile.isDirectory) return false // 判断是否是文件
        val fis = FileInputStream(srcFile)
        val fos = FileOutputStream(destFile)
        var readLen = 0
        val buf = ByteArray(10240)
        while (fis.read(buf).also { readLen = it } != -1) {
            fos.write(buf, 0, readLen)
        }
        fos.flush()
        fos.close()
        fis.close()
        return true
    }

    fun copyAssetFileToSDCard(
        context: Context,
        filePath: String?,
        fileName: String?,
        destFileName: String?
    ) {
        val assetManager = context.assets
        val outputFile = File(filePath, destFileName)
        try {
            assetManager.open(fileName!!).use { `is` ->
                FileOutputStream(outputFile).use { os ->
                    val buffer = ByteArray(1024)
                    var length: Int
                    while (`is`.read(buffer).also { length = it } != -1) {
                        os.write(buffer, 0, length)
                    }
                }
            }
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    /**
     * 文件是否存在
     *
     * @param filePath filePath
     */
    fun fileExists(filePath: String?): Boolean {
        return try {
            val file = File(filePath)
            file.exists() && getFileSize(file) > 0
        } catch (e: Exception) {
            false
        }
    }

    /**
     * 删除文件(不包含目录)
     *
     * @param file
     */
    @JvmStatic
    fun deleteFile(file: File) {
        if (file.exists()) { // 判断文件是否存在
            if (file.isFile) { // 判断是否是文件
                file.delete() // delete()方法 你应该知道 是删除的意思;
            } else if (file.isDirectory) { // 否则如果它是一个目录
                val files = file.listFiles() // 声明目录下所有的文件 files[];
                for (i in files.indices) { // 遍历目录下所有的文件
                    deleteFile(files[i]) // 把每个文件 用这个方法进行迭代
                }
            }
            // file.delete();
        } else {
            // SystemInfo.showToast(GrrzXrzAct.this, "文件不存在!");
        }
    }

    /**
     * 打开SD卡上指定的文件
     */
    fun browseFile(
        filepath: String, fileName: String,
        activity: Activity
    ) {
        // String filepath = String.format("%s/%s/%s",
        // SystemInfo.getSdCardPath(), dirName, fileName);
        val file = File(filepath)
        Log.i("test", "filepath: $filepath ,fileName: $fileName")
        if (file.exists()) {
            // 设置文件类型
            val type = checkFileType(fileName)
            Log.i("test", "type: $type")
            Log.i("test", "取文件类型完成!")
            val intent = Intent()
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            intent.action = Intent.ACTION_VIEW
            if (type != "") {
                try {
                    intent.setDataAndType(Uri.fromFile(file), type)
                    activity.startActivity(intent)
                } catch (e: Exception) {
                    Toast.makeText(
                        activity,
                        "文件打开异常,请到SD卡" + "MobilePlatform" + "目录中浏览！",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            } else Toast.makeText(activity, "该文件类型无法识别！", Toast.LENGTH_SHORT)
                .show()
        }
    }

    /**
     * 缓存写入文件数据data/data目录中
     *
     * @param ser
     * @param file
     * @return
     */
    fun saveObject(
        activity: Activity, ser: Serializable?,
        file: String?
    ): Boolean {
        var fos: FileOutputStream? = null
        var oos: ObjectOutputStream? = null
        return try {
            fos = activity.openFileOutput(file, Context.MODE_PRIVATE)
            oos = ObjectOutputStream(fos)
            oos.writeObject(ser)
            oos.flush()
            true
        } catch (e: Exception) {
            e.printStackTrace()
            false
        } finally {
            try {
                oos!!.close()
            } catch (e: Exception) {
            }
            try {
                fos!!.close()
            } catch (e: Exception) {
            }
        }
    }

    /**
     * 写string到文件
     *
     * @param str
     */
    fun writePiciFile(str: String?) {
        var writer: FileWriter? = null
        try {
            val f = File(
                Environment.getExternalStorageDirectory()
                    .toString() + "/pici.bin"
            )
            if (!f.exists()) {
                f.createNewFile()
            }
            writer = FileWriter(f, false)
            writer.write(str)
            writer.flush()
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            try {
                writer!!.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

    val piciContent: String?
        /**
         * 读取文件
         *
         * @return
         */
        get() {
            var fileIS: FileInputStream? = null
            var buf: BufferedReader? = null
            try {
                val f = File(
                    Environment.getExternalStorageDirectory()
                        .toString() + "/pici.bin"
                )
                if (!f.exists()) {
                    f.createNewFile()
                }
                fileIS = FileInputStream(f.absolutePath)
                buf = BufferedReader(InputStreamReader(fileIS))
                return buf.readLine()
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                try {
                    buf!!.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
                try {
                    fileIS!!.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
            return null
        }

    /**
     * 创建目录
     */
    fun createCatalog(path: String?) {
        val userFile = File(path)
        if (userFile.exists()) {
            if (userFile.isFile) {
                userFile.delete()
                userFile.mkdirs()
            }
        } else {
            userFile.mkdirs()
        }
    }

    /**
     * 写入序列化对象文件
     */
    fun writeSerFile(cachePath: String?, obj: Serializable?) {
        val file = File(cachePath)
        if (file.exists()) {
            try {
                deleteFile(file)
                file.createNewFile()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        var oos: ObjectOutputStream? = null
        var fos: FileOutputStream? = null
        try {
            fos = FileOutputStream(file)
            oos = ObjectOutputStream(fos)
            oos.writeObject(obj)
            oos.flush()
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            try {
                oos!!.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
            try {
                fos!!.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

    /**
     * 读取序列化对象文件
     */
    fun readSerFile(cachePath: String?): Serializable? {
        val file = File(cachePath)
        if (file.exists()) {
            var objectInputStream: ObjectInputStream? = null
            var fis: FileInputStream? = null
            try {
                fis = FileInputStream(file)
                objectInputStream = ObjectInputStream(fis)
                return objectInputStream.readObject() as Serializable
            } catch (e: Exception) {
                e.printStackTrace()
            } finally {
                try {
                    objectInputStream!!.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
                try {
                    fis!!.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }
        return null
    }

    /**
     * 获取文件中指定文件的指定单位的大小(后面部分方法的总调用)
     *
     * @param filePath 文件路径
     * @param sizeType 获取大小的类型1为B、2为KB、3为MB、4为GB
     * @return double值的大小
     */
    fun getFileOrFilesSize(filePath: String?, sizeType: Int): Double {
        val file = File(filePath)
        var blockSize: Long = 0
        try {
            blockSize = if (file.isDirectory) {
                getFileSizes(file)
            } else {
                getFileSize(file)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Log.e("获取文件大小", "获取失败!")
        }
        return FormetFileSize(blockSize, sizeType)
    }

    /**
     * 获取下载 URL 的文件的大小
     */
    fun getFileSize(address: String?): Long {
        var filesize: Long = 0
        var urlConn: HttpURLConnection? = null
        try {
            val url = URL(address)
            urlConn = url.openConnection() as HttpURLConnection
            urlConn!!.connectTimeout = 10000
            urlConn.readTimeout = 10000
            urlConn.connect()
            filesize = urlConn.contentLength.toLong()
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            urlConn!!.disconnect()
        }
        return filesize
    }

    fun getFileNameWithType(path: String): String? {
        if (TextUtils.isEmpty(path)) {
            return null
        }
        val start = path.lastIndexOf("/")
        return if (start != -1) {
            path.substring(start + 1, path.length)
        } else {
            null
        }
    }

    /**
     * 取文件类型
     */
    fun checkFileType(fileName: String): String {
        val fileType = Properties()
        Log.i("test", "取文件类型!")
        try {
            fileType.load(
                AwFileUtil::class.java
                    .getResourceAsStream("/assets/andoirfiletype.properties")
            )
        } catch (e: IOException) {
            Log.e("Utils", e.toString())
            e.printStackTrace()
        }
        val length = fileName.length
        val dotPosition = fileName.lastIndexOf(".")
        val sufix = fileName.substring(dotPosition, length)
        return fileType.getProperty(sufix)
    }

    /**
     * 调用此方法自动计算指定文件或指定文件夹的大小
     *
     * @param filePath 文件路径
     * @return 计算好的带B、KB、MB、GB的字符串
     */
    fun getAutoFileOrFilesSize(filePath: String?): String {
        val file = File(filePath)
        var blockSize: Long = 0
        try {
            blockSize = if (file.isDirectory) {
                getFileSizes(file)
            } else {
                getFileSize(file)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Log.e("获取文件大小", "获取失败!")
        }
        return FormetFileSize(blockSize)
    }

    /**
     * 获取指定文件大小
     *
     * @throws Exception
     */
    @Throws(Exception::class)
    private fun getFileSize(file: File): Long {
        var size: Long = 0
        if (file.exists()) {
            val fis = FileInputStream(file)
            size = fis.available().toLong()
        } else {
            file.createNewFile()
            Log.e("获取文件大小", "文件不存在!")
        }
        return size
    }

    /**
     * 获取指定文件夹(目录)大小
     *
     * @param f
     * @return
     * @throws Exception
     */
    @Throws(Exception::class)
    private fun getFileSizes(f: File): Long {
        var size: Long = 0
        val flist = f.listFiles()
        for (i in flist.indices) {
            size = if (flist[i].isDirectory) {
                size + getFileSizes(flist[i])
            } else {
                size + getFileSize(flist[i])
            }
        }
        return size
    }

    /**
     * 转换文件大小
     *
     * @param fileS
     * @return
     */
    private fun FormetFileSize(fileS: Long): String {
        val df = DecimalFormat("#.00")
        var fileSizeString = ""
        val wrongSize = "0B"
        if (fileS == 0L) {
            return wrongSize
        }
        fileSizeString = if (fileS < 1024) {
            df.format(fileS.toDouble()) + "B"
        } else if (fileS < 1048576) {
            df.format(fileS.toDouble() / 1024) + "KB"
        } else if (fileS < 1073741824) {
            df.format(fileS.toDouble() / 1048576) + "MB"
        } else {
            df.format(fileS.toDouble() / 1073741824) + "GB"
        }
        return fileSizeString
    }

    /**
     * 转换文件大小,指定转换的类型
     *
     * @param fileS
     * @param sizeType
     * @return
     */
    private fun FormetFileSize(fileS: Long, sizeType: Int): Double {
        val df = DecimalFormat("#.00")
        var fileSizeLong = 0.0
        when (sizeType) {
            SIZETYPE_B -> fileSizeLong = java.lang.Double.valueOf(df.format(fileS.toDouble()))
            SIZETYPE_KB -> fileSizeLong =
                java.lang.Double.valueOf(df.format(fileS.toDouble() / 1024))

            SIZETYPE_MB -> fileSizeLong =
                java.lang.Double.valueOf(df.format(fileS.toDouble() / 1048576))

            SIZETYPE_GB -> fileSizeLong = java.lang.Double.valueOf(
                df
                    .format(fileS.toDouble() / 1073741824)
            )

            else -> {}
        }
        return fileSizeLong
    }

    /**
     * @param @param  bytes
     * @param @return
     * @return String
     * @throws
     * @Title: bytes2kb
     * @Description: TODO byte to kb or mb
     */
    fun bytes2kb(bytes: Long): String {
        val filesize = BigDecimal(bytes)
        val megabyte = BigDecimal(1024 * 1024)
        var returnValue = filesize.divide(megabyte, 2, BigDecimal.ROUND_UP)
            .toFloat()
        if (returnValue > 1) {
            return returnValue.toString() + "MB"
        }
        val kilobyte = BigDecimal(1024)
        returnValue = filesize.divide(kilobyte, 2, BigDecimal.ROUND_UP)
            .toFloat()
        return returnValue.toString() + "KB"
    }

    @JvmStatic
    fun getMIMEType(file: File): String {
        var type = "*/*"
        val fName = file.name
        // 获取后缀名前的分隔符"."在fName中的位置。
        val dotIndex = fName.lastIndexOf(".")
        if (dotIndex < 0) {
            return type
        }
        /* 获取文件的后缀名 */
        val end = fName.substring(dotIndex, fName.length).lowercase(
            Locale.getDefault()
        )
        if (end === "") return type
        // 在MIME和文件类型的匹配表中找到对应的MIME类型。
        for (i in MIME_MapTable.indices) {
            if (end == MIME_MapTable[i][0]) type = MIME_MapTable[i][1]
        }
        return type
    }

    // 可以自己随意添加
    var MIME_MapTable = arrayOf(
        arrayOf(".3gp", "video/3gpp"),
        arrayOf(".apk", "application/vnd.android.package-archive"),
        arrayOf(".asf", "video/x-ms-asf"),
        arrayOf(".avi", "video/x-msvideo"),
        arrayOf(".bin", "application/octet-stream"),
        arrayOf(".bmp", "image/bmp"),
        arrayOf(".c", "text/plain"),
        arrayOf(".class", "application/octet-stream"),
        arrayOf(".conf", "text/plain"),
        arrayOf(".cpp", "text/plain"),
        arrayOf(".doc", "application/msword"),
        arrayOf(
            ".docx",
            "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
        ),
        arrayOf(".xls", "application/vnd.ms-excel"),
        arrayOf(
            ".xlsx",
            "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        ),
        arrayOf(".exe", "application/octet-stream"),
        arrayOf(".gif", "image/gif"),
        arrayOf(".gtar", "application/x-gtar"),
        arrayOf(".gz", "application/x-gzip"),
        arrayOf(".h", "text/plain"),
        arrayOf(".htm", "text/html"),
        arrayOf(".html", "text/html"),
        arrayOf(".jar", "application/java-archive"),
        arrayOf(".java", "text/plain"),
        arrayOf(".jpeg", "image/jpeg"),
        arrayOf(".jpg", "image/jpeg"),
        arrayOf(".js", "application/x-javascript"),
        arrayOf(".log", "text/plain"),
        arrayOf(".m3u", "audio/x-mpegurl"),
        arrayOf(".m4a", "audio/mp4a-latm"),
        arrayOf(".m4b", "audio/mp4a-latm"),
        arrayOf(".m4p", "audio/mp4a-latm"),
        arrayOf(".m4u", "video/vnd.mpegurl"),
        arrayOf(".m4v", "video/x-m4v"),
        arrayOf(".mov", "video/quicktime"),
        arrayOf(".mp2", "audio/x-mpeg"),
        arrayOf(".mp3", "audio/x-mpeg"),
        arrayOf(".mp4", "video/mp4"),
        arrayOf(".mpc", "application/vnd.mpohun.certificate"),
        arrayOf(".mpe", "video/mpeg"),
        arrayOf(".mpeg", "video/mpeg"),
        arrayOf(".mpg", "video/mpeg"),
        arrayOf(".mpg4", "video/mp4"),
        arrayOf(".mpga", "audio/mpeg"),
        arrayOf(".msg", "application/vnd.ms-outlook"),
        arrayOf(".ogg", "audio/ogg"),
        arrayOf(".pdf", "application/pdf"),
        arrayOf(".png", "image/png"),
        arrayOf(".pps", "application/vnd.ms-powerpoint"),
        arrayOf(".ppt", "application/vnd.ms-powerpoint"),
        arrayOf(
            ".pptx",
            "application/vnd.openxmlformats-officedocument.presentationml.presentation"
        ),
        arrayOf(".prop", "text/plain"),
        arrayOf(".rc", "text/plain"),
        arrayOf(".rmvb", "audio/x-pn-realaudio"),
        arrayOf(".rtf", "application/rtf"),
        arrayOf(".sh", "text/plain"),
        arrayOf(".tar", "application/x-tar"),
        arrayOf(".tgz", "application/x-compressed"),
        arrayOf(".txt", "text/plain"),
        arrayOf(".wav", "audio/x-wav"),
        arrayOf(".wma", "audio/x-ms-wma"),
        arrayOf(".wmv", "audio/x-ms-wmv"),
        arrayOf(".wps", "application/vnd.ms-works"),
        arrayOf(".xml", "text/plain"),
        arrayOf(".z", "application/x-compress"),
        arrayOf(".zip", "application/x-zip-compressed"),
        arrayOf(".tif", "image/tiff"),
        arrayOf(".tiff", "image/tiff"),
        arrayOf(".amr", "video/*")
    )
}